React Server Component
クライアントアプリケーションや SSR サーバとは別の環境で、バンドル前に事前にレンダーされます。 React Server Components の “server” とはこの別の環境を指しています。サーバコンポーネントは、CI サーバでビルド時に一度だけ実行することも、ウェブサーバを使用してリクエストごとに実行することもできます。
特徴
サーバサイドでのみ実行されるコンポーネント
従来の React における SSR でのコンポーネントは、ブラウザとサーバの両方で実行されていた よく混同されるが、SSR とは異なる radish-miyazaki.icon レンダリング結果 が異なる
各々が独立しているので、同じプロセス、マシンで動かす必要もない
コンポーネントの JS ファイルがブラウザに送られることが無い
コンポーネント上から直接外部 API のデータを取得し、レンダリングするといったことが可能に
code:tsx
async function getPosts() {
.then((res) => res.json());
return data.posts;
}
export default async function ServerComponent() {
const posts = getPosts()
return (
<div>
<h1>Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<a href={post.url}>{post.title}</a>
</li>
))}
</ul>
</div>
)
}
fetch はコンポーネント内から呼び出さないようにする
理由
どういったデータを取得しているか分かりやすい
リクエストのメモ化の考慮漏れが起きづらい
1. Promise.all を用いる
code:tsx
export default async function Page({ params, searchParams }: Props) {
getCategory(photo.categoryName),
getPhotos()
]);
// ...
}
2. 子 Server Component ごとにサーバサイドのデータを取得
e.g. Next.js における RSC
App Router 内で実装されるコンポーネントは、デフォルトで React Server Component として扱われる By default, Next.js uses Server Components.
RSC と CC は以下のようなフローでレンダリングされる
サーバサイド
Each chunk is rendered in two steps:
1. React renders Server Components into a special data format called the React Server Component Payload (RSC Payload).
2. Next.js uses the RSC Payload and Client Component JavaScript instructions to render HTML on the server.
クライアントサイド
Then, on the client:
1. The HTML is used to immediately show a fast non-interactive preview of the route - this is for the initial page load only.
2. The React Server Components Payload is used to reconcile the Client and Server Component trees, and update the DOM.
3. The JavaScript instructions are used to hydrate Client Components and make the application interactive.
1. サーバで生成された初期表示のための HTML を元に、すぐに非インタラクティブな画面を表示する
参考
常にレンダリングの流れは不変であり、サーバーサイド→クライアントサイドの順番で行われる
CCがレンダリングされるときにはすでにSCのレンダリングが完了しています。
CCからSCを読み込めてしまうと、その時点で新たなサーバーへのリクエストが発生してしまうので、CCにSCを読み込むことはできません。
code:ts
'use client'
import ServerComponent from './Server-Component'
export default function ClientComponent() {
return (
<>
<ServerComponent />
</>
)
}
code:ts
export default function Page() {
return (
<ClientComponent>
<ServerComponent />
</ClientComponent>
)
}
参考